#pragma once

#ifndef DRAW_POLYGON_HANDLER_H_
#define DRAW_POLYGON_HANDLER_H_

#include <osg/LineWidth>
#include <osg/Point>
#include <osg/ShapeDrawable>
#include <osg/BlendFunc>
#include <osgViewer/Viewer>
#include <osgGA/GUIEventHandler>
#include <osgUtil/Optimizer>

class DrawPolygonHandler : public osgGA::GUIEventHandler
{
public:
	DrawPolygonHandler();

	bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa);

	void StartEditing();
	void StopEditing();

	float GetBoxTopHeight();
	float GetBoxBottomHeight();
	float AdjustBoxTopHeight(float step = 1.f);
	float AdjustBoxBottomHeight(float step = 1.f);

	float GetPlaneHeight();
	float AdjustPlaneHeight(float step = 1.f);

	const osg::Box *GetBoundingBox();
	const osg::Vec3Array *GetVertices();
	osg::Geode *GetPolygonGeode();

	void Clear();
private:
	struct geometryUpdateCallback : public osg::Drawable::UpdateCallback
	{
		geometryUpdateCallback() { _numVertices = 0; _validity1 = _validity2 = false; }

		virtual void update(osg::NodeVisitor *nv, osg::Drawable *drawable);
		void SetValidity(bool val);

	private:
		bool         _validity1, _validity2;
		unsigned int _numVertices;
	};

	void _showBoxAndPlane(osg::Vec3Array *vertices);

	osg::Vec4 _getBoundingRect(const osg::Vec3Array *vertices);
	bool _getIntersectPoint(osgViewer::Viewer            *viewer,
		                    const osgGA::GUIEventAdapter &ea,
		                    osg::Vec3d                   &intersectPoint);
	bool _checkVertexValidity(const osg::Vec3Array *vertices, bool finishing = false);
	bool _areLineSegmentsCross(const osg::Vec3 &line1_p1, const osg::Vec3 &line1_p2,
		                       const osg::Vec3 &line2_p1, const osg::Vec3 &line2_p2);

	osg::ref_ptr<osg::Geode>         _polygonGeode;

	osg::ref_ptr<osg::Geometry>      _geometry_polygon;
	osg::ref_ptr<osg::Vec3Array>     _vertexArray;
	osg::ref_ptr<osg::Vec4Array>     _colorArray;

	osg::ref_ptr<osg::ShapeDrawable> _shapeDrawable_box;
	osg::ref_ptr<osg::Box>           _shape_box;

	osg::ref_ptr<osg::Geometry>      _geometry_plane;
	osg::ref_ptr<osg::Vec3Array>     _vertexArray_plane;

	osg::ref_ptr<geometryUpdateCallback> _geomUpdateCallback;

	osg::Vec4 _color_normal, _color_end;
	osg::Vec4 _color_box;

	bool _isEditing;
	bool _isDrawing;
	bool _hasFinishedValidDrawing;
	float _x, _y;
};

#endif